package com.sugon.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.consts.SparePartScarpStatus;
import com.sugon.dao.DevRetreadRecordDao;
import com.sugon.entity.*;
import com.sugon.modules.sparepart.consts.MaterialBaseConst;
import com.sugon.modules.sparepart.consts.MaterialBaseProgress;
import com.sugon.modules.sparepart.consts.SparePartsConsumeType;
import com.sugon.modules.workflow.consts.OaWorkflowProcesses;
import com.sugon.service.*;
import com.sugon.utils.ProcessInfoEnum;
import com.sugon.utils.ShiroUtils;
import com.sugon.utils.SysMsgType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 修旧利废记录/改良改善台账Service实现类
 *
 * @author sugon
 * @date 2019-07-19 08:33:39
 */
@Service("devRetreadRecordService")
public class DevRetreadRecordServiceImpl implements DevRetreadRecordService {
    @Autowired
    private DevRetreadRecordDao devRetreadRecordDao;
    @Autowired
    private SysProcessInfoService sysProcessInfoService;
    @Autowired
    private SysMsgService sysMsgService;
    @Resource
    private SparePartConsumRecordService sparePartConsumRecordService;
    @Resource
    private ScarpListService scarpListService;
    @Resource
    private SysOaProcessService processService;
    @Resource
    private SparePartService sparePartService;
    @Resource
    private MaterialRecordService materialRecordService;
    @Resource
    private MaterialBaseService materialBaseService;

    /**
     * @param id 主键
     * @return
     */
    @Override
    public DevRetreadRecordEntity queryObject(String id) {
        return devRetreadRecordDao.queryObject(id);
    }

    /**
     * @param map 参数
     * @return
     */
    @Override
    public List<DevRetreadRecordEntity> queryList(Map<String, Object> map) {
        return devRetreadRecordDao.queryList(map);
    }

    /**
     * @param map 参数
     * @return
     */
    @Override
    public int queryTotal(Map<String, Object> map) {
        return devRetreadRecordDao.queryTotal(map);
    }

    /**
     * @param devRetreadRecord 实体
     * @return
     */
    @Override
    public int save(DevRetreadRecordEntity devRetreadRecord) {
        devRetreadRecord.setId(RandomUtil.randomString(32));
        devRetreadRecord.setCreateUser(ShiroUtils.getUserId());
        devRetreadRecord.setCreateDate(new Date());
        devRetreadRecord.setDelFlag(1);
        sysProcessInfoService.saveProcessInfo(devRetreadRecord.getId(), ProcessInfoEnum.DEV_XJGL, 0, null);
        SysMsgEntity sysMsgEntity = new SysMsgEntity();
        String Id = devRetreadRecord.getId();
        sysMsgEntity.setDataId(Id);
        if (devRetreadRecord.getType() == 1) {
            sysMsgEntity.setDataUrl("../device/devretreadrecord.html?Id" + Id);
        } else {
            sysMsgEntity.setDataUrl("../device/devRecord.html?Id" + Id);
        }
        sysMsgService.addApproveItem(ProcessInfoEnum.DEV_XJGL, sysMsgEntity, 0);
        return devRetreadRecordDao.save(devRetreadRecord);
    }

    /**
     * @param devRetreadRecord 实体
     * @return
     */
    @Override
    public int update(DevRetreadRecordEntity devRetreadRecord) {
        devRetreadRecord.setUpdateUser(ShiroUtils.getUserId());
        devRetreadRecord.setUpdateDate(new Date());
        int rows = devRetreadRecordDao.update(devRetreadRecord);
        if (rows > 0) {
            SysMsgEntity sysMsgEntity = new SysMsgEntity();
            String Id = devRetreadRecord.getId();
            sysMsgEntity.setDataId(Id);
            if (devRetreadRecord.getType() == 1) {
                sysMsgEntity.setDataUrl("../device/devretreadrecord.html?Id" + Id);
            } else {
                sysMsgEntity.setDataUrl("../device/devRecord.html?Id" + Id);
            }
            sysMsgService.addApproveItem(ProcessInfoEnum.DEV_XJGL, sysMsgEntity, 0);
        }
        return rows;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int perfect(DevRetreadRecordEntity devRetreadRecord) {
        // 设置完善记录用户所在的车间
        devRetreadRecord.setExpUnit(ShiroUtils.getWorkshop());
        /*
            校验是否已修复
            如果未能修复，直接生成报废记录
            如果已修复，需要计算成本等信息
         */
        int updateNum = update(devRetreadRecord);
        if (updateNum > 0) {
            Integer isFixed = devRetreadRecord.getIsFixed();
            if (NumberUtil.equals(isFixed, 2)) {
                // 如果已关联报废记录，需要调整状态为已修复
                if (StrUtil.isNotEmpty(devRetreadRecord.getScarpRecordId())) {
                    ScarpListEntity scarpRecord = scarpListService.queryObject(devRetreadRecord.getScarpRecordId());
                    Assert.notNull(scarpRecord);
                    scarpRecord.setStatus(SparePartScarpStatus.SCARP.getValue());
                    scarpListService.update(scarpRecord);
                    // 记录自主修复处理失败
                    processService.generateProcessHandleRecord(OaWorkflowProcesses.SP_SCARP.getBusType(), scarpRecord.getId(), "自主修复", 2, devRetreadRecord.getRemark());
                }
            } else {
                // 如果已关联报废记录，需要调整状态为已修复
                if (StrUtil.isNotEmpty(devRetreadRecord.getScarpRecordId())) {
                    ScarpListEntity scarpRecord = scarpListService.queryObject(devRetreadRecord.getScarpRecordId());
                    Assert.notNull(scarpRecord);
                    scarpRecord.setStatus(SparePartScarpStatus.CZ_ED.getValue());
                    scarpListService.update(scarpRecord);
                    // 1、记录自主修复-已修复处理记录
                    processService.generateProcessHandleRecord(OaWorkflowProcesses.SP_SCARP.getBusType(), scarpRecord.getId(), "自主修复", 1, devRetreadRecord.getRemark());
                }
                // 2、更新自主维修台账中：维修成本、节约成本信息
                if (devRetreadRecord.getPrimeCost() == null || NumberUtil.equals(devRetreadRecord.getPrimeCost(), BigDecimal.ZERO)) {
                    List<SparePartConsumRecordEntity> spConsumeRecordList = sparePartConsumRecordService.queryList(SparePartsConsumeType.SCARP_REPAIR.name(), devRetreadRecord.getId());
                    if (CollectionUtil.isNotEmpty(spConsumeRecordList)) {
                        devRetreadRecord.setPrimeCost(spConsumeRecordList.stream().map(consumeRecord -> NumberUtil.mul(consumeRecord.getUnitPrice(), consumeRecord.getNum())).reduce(BigDecimal.ZERO, BigDecimal::add));
                    } else {
                        devRetreadRecord.setPrimeCost(BigDecimal.ZERO);
                    }
                }
                // 如果未设置节约价值，则根据原值 - 维修成本得出
                if (devRetreadRecord.getLessCost() == null || NumberUtil.equals(devRetreadRecord.getLessCost(), BigDecimal.ZERO)) {
                    devRetreadRecord.setLessCost(NumberUtil.sub(devRetreadRecord.getOrigVal(), devRetreadRecord.getPrimeCost()));
                }
                update(devRetreadRecord);
                // 3、生成领料单+领料明细
                SparePartEntity sp = sparePartService.queryObject(devRetreadRecord.getSpareId());
                Assert.notNull(sp);
                // 保存领料单
                MaterialBaseEntity materialBase = new MaterialBaseEntity();
                materialBase.setDeptId(devRetreadRecord.getExpUnit());
                materialBase.setPurpose("自主修复后入线边库");
                materialBase.setPicker(devRetreadRecord.getUpdateUser());
                materialBase.setPickDate(DateUtil.date());
                materialBase.setType(0);
                materialBase.setProgress(MaterialBaseProgress.END_OUTBOUND);
                materialBase.setMaterialType(MaterialBaseConst.XF);
                materialBase.setRemark("系统自动生成插入，无需审核");
                materialBaseService.save(materialBase);
                // 保存领料明细
                MaterialRecordEntity materialItem = new MaterialRecordEntity();
                materialItem.setMaterial(materialBase.getId());
                materialItem.setSpareCode(sp.getPartCode());
                materialItem.setDeptCode(devRetreadRecord.getExpUnit());
                materialItem.setPostion("自主修复");
                materialItem.setSpareName(sp.getName());
                materialItem.setNum(devRetreadRecord.getRetNum());
                materialRecordService.save(materialItem);
            }
        }
        return 0;
    }

    /**
     * @param ids
     */
    @Override
    public void check(String[] ids) {
        for (String id : ids) {
            DevRetreadRecordEntity devRetreadRecordEntity = devRetreadRecordDao.queryObject(id);
            DevRetreadRecordEntity devRetreadRecord = new DevRetreadRecordEntity();
            devRetreadRecord.setId(devRetreadRecordEntity.getId());
            //sysProcessInfoService.saveProcessInfo(devRetreadRecord.getId(), ProcessInfoEnum.DEV_XJGL, devRetreadRecord.getApprovalStatus(), null);
            SysMsgEntity sysMsgEntity = new SysMsgEntity();
            String Id = devRetreadRecord.getId();
            sysMsgEntity.setDataId(Id);
            sysMsgEntity.setDataType(ProcessInfoEnum.DEV_XJGL);
            sysMsgEntity.setDataFlag(SysMsgType.DATA_DEL_END);
            sysMsgService.allMsgData(sysMsgEntity);
            devRetreadRecordDao.update(devRetreadRecord);
        }
    }

    /**
     * @param id
     * @return
     */
    @Override
    public int delete(String id) {
        return devRetreadRecordDao.delete(id);
    }

    /**
     * @param ids
     * @return
     */
    @Override
    public int deleteBatch(String[] ids) {
        return devRetreadRecordDao.deleteBatch(ids);
    }
}
